package com.teatrace.commons.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.teatrace.commons.util.HibernateUtils;

public class OpenSessionInViewFilter implements Filter {

	private static final Logger logger = Logger.getLogger(OpenSessionInViewFilter.class);
	
	private static final String filteredAttibuteKey = "com.teatrace.FILTERED";
	
	private static List<String> noNeedFilterFile = new ArrayList<String>();
	
	static {
		noNeedFilterFile.add(".jsp");
		noNeedFilterFile.add(".css");
		noNeedFilterFile.add(".js");
		noNeedFilterFile.add(".jpg");
		noNeedFilterFile.add(".jpeg");
		noNeedFilterFile.add(".gif");
		noNeedFilterFile.add(".bmp");
		noNeedFilterFile.add(".html");
	}
	
	public void destroy() {
		logger.debug("OpenSessionInViewFilter destroy");
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
			throw new ServletException("OpenSessionInViewFilter just supports HTTP requests");
		}
		
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		
		if(!isNeedFiltered(httpRequest.getServletPath())) {
			logger.debug(httpRequest.getServletPath() + " not need filter! skip..");
			chain.doFilter(request, response);
			return;
		}
		
		httpRequest.setAttribute(filteredAttibuteKey, Boolean.TRUE);
		doBeginSession();
		
		try {
			chain.doFilter(request, response);
		} finally {
			doCloseSession();
			httpRequest.removeAttribute(filteredAttibuteKey);
		}
	}
	
	private boolean isNeedFiltered(String path) {
		if(path == null || path.equals("")) {
			return true;
		}
		for(String suffix : noNeedFilterFile) {
			if(path.endsWith(suffix)) {
				return false;
			}
		}
		return true;
	}
	
	private void doBeginSession() {
		logger.debug("OpenSessionInViewFilter doBeginSession");
		HibernateUtils.getCurrentSession();
	}
	
	private void doCloseSession() {
		logger.debug("OpenSessionInViewFilter doCloseSession");
		HibernateUtils.getCurrentSession().close();
		
	}

	public void init(FilterConfig config) throws ServletException {
		logger.debug("OpenSessionInViewFilter init");
	}

}
